package com.hpsk.utils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.hpsk.annotations.ExcelExport;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Cleanup;

import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelShopUtils {

    public static List<Map<String, Object>> getExcelData(String filePath) {
        @Cleanup
        ExcelReader reader = ExcelUtil.getReader(FileUtil.file(filePath));
        return reader.readAll();
    }

    public static void getExcelWriterData(List<?> data, String outFilePath, String title, Class<?> o) {
        if (FileUtil.exist(FileUtil.file(outFilePath))) {
            FileUtil.del(FileUtil.file(outFilePath));
        }
        ExcelWriter writer = ExcelUtil.getWriter(outFilePath);
        addHeaderAlias(o, writer, title);
        writer.write(data, true);
        writer.close();
    }

    public static void getExcelWriterData(List<?> data, HttpServletResponse response, String title, Class<?> o) throws IOException {
        response.setHeader("Content-Disposition", "attachment;filename=" + LocalDate.now().format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN)) + ".xlsx");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setContentType("application/octet-stream;charset=UTF-8");
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        ServletOutputStream out = response.getOutputStream();
        ExcelWriter writer = ExcelUtil.getWriter();
        addHeaderAlias(o, writer, title);
        writer.write(data, true);
        writer.flush(out, true);
        writer.close();
    }

    private static void addHeaderAlias(Class<?> o, ExcelWriter writer, String title) {
        Field[] declaredFields = o.getDeclaredFields();
        for (int i = 0; i < declaredFields.length; i++) {
            Field declaredField = declaredFields[i];
            ExcelExport excelExclude = declaredField.getAnnotation(ExcelExport.class);
            if (excelExclude != null) {
                String name = excelExclude.name();
                boolean export = excelExclude.isExport();
                if (export) {
                    writer.addHeaderAlias(declaredField.getName(), ObjectUtil.isNotEmpty(name) ? name : declaredField.getName());
                }
            }
        }
        int size = writer.getHeaderAlias().size();
        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        writer.merge(size - 1, title);
    }

    public static List<Map<String, Object>> getDataMap(ExcelReader excelReader) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            List<List<Object>> read = excelReader.read();
            Map<Integer, String> headerMap = new HashMap<>();
            for (int i = 0; i < read.size(); i++) {
                List<Object> excelRow = read.get(i);
                if (i == 0) {
                    for (int j = 0; j < excelRow.size(); j++) {
                        headerMap.put(j, excelRow.get(j).toString());
                    }
                } else {
                    Map<String, Object> dataMap = new HashMap<>();
                    for (int j = 0; j < excelRow.size(); j++) {
                        Object o = excelRow.get(j);
                        if (o == null) {
                            dataMap.put(headerMap.get(j), "");
                        } else {
                            dataMap.put(headerMap.get(j), o);
                        }
                        list.add(dataMap);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("获取excel失败！");
        } finally {
            excelReader.close();
        }
        return list;
    }

    public static void main(String[] args) {
        String filePath = "D:\\test.xls";
        List<Map<String, Object>> data = ExcelShopUtils.getExcelData(filePath);
        System.out.println(JSONUtil.toJsonPrettyStr(data));
    }
}
